package com.dwx.guli.service.ucenter.controller.api;


import com.dwx.guli.common.util.HttpClientUtils;
import com.dwx.guli.service.base.exception.GuliException;
import com.dwx.guli.service.base.helper.JwtHelper;
import com.dwx.guli.service.base.helper.JwtInfo;
import com.dwx.guli.service.base.result.R;
import com.dwx.guli.service.base.result.ResultCodeEnum;
import com.dwx.guli.service.ucenter.entity.Member;
import com.dwx.guli.service.ucenter.feign.OssFileService;
import com.dwx.guli.service.ucenter.service.MemberService;
import com.dwx.guli.service.ucenter.util.UcenterProperties;
import com.google.gson.Gson;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.UUID;

@Slf4j
@Api(tags = "微信登录")
@CrossOrigin
@Controller
@RequestMapping("/api/ucenter/wx")
public class ApiWxController {
    @Autowired
    private UcenterProperties ucenterProperties;
    @Autowired
    private MemberService memberService;
    @Autowired
    private OssFileService ossFileService;
//    @Autowired
//    private RedisTemplate redisTemplate;
    @ApiOperation("获取code")
    @GetMapping("login")
    public String genQrConnect(HttpSession session){
        String baseUrl="https://open.weixin.qq.com/connect/qrconnect?" +
                "appid=%s" +
                "&redirect_uri=%s" +
                "&response_type=code" +
                "&scope=snsapi_login" +
                "&state=%s" +
                "#wechat_redirect";
        String appId = ucenterProperties.getAppId();
        String redirectUri = ucenterProperties.getRedirectUri();
        try {
            redirectUri = URLEncoder.encode(redirectUri, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            log.error(ExceptionUtils.getStackTrace(e));
            throw new GuliException(ResultCodeEnum.URL_ENCODE_ERROR);
        }
        String state = UUID.randomUUID().toString();
        session.setAttribute("wx_open_state", state);
        String qrcodeUrl = String.format(baseUrl, appId, redirectUri, state);
        return "redirect:"+qrcodeUrl;
    }
    @GetMapping("callback")
    public String callback(String code, String state, HttpSession session){
        if(StringUtils.isEmpty(code)||StringUtils.isEmpty(state)){
            log.error("非法回调请求");
            throw new GuliException(ResultCodeEnum.ILLEGAL_CALLBACK_REQUEST_ERROR);
        }
        String  sessionState = (String)session.getAttribute("wx_open_state");
        if(!sessionState.equals(state)){
            log.error("非法回调请求");
            throw new GuliException(ResultCodeEnum.ILLEGAL_CALLBACK_REQUEST_ERROR);
        }
        String accessTokenUrl="https://api.weixin.qq.com/sns/oauth2/access_token?" +
                "appid=" +ucenterProperties.getAppId()+
                "&secret=" +ucenterProperties.getAppSecret()+
                "&code=" +code+
                "&grant_type=authorization_code";
        HttpClientUtils client=new HttpClientUtils(accessTokenUrl);
        String result="";
        try {
            client.setHttps(true);
            client.get();
            result = client.getContent();
        } catch (Exception e) {
            log.error("获取access_token失败");
            throw new GuliException(ResultCodeEnum.FETCH_ACCESSTOKEN_FAILD);
        }
        Gson gson=new Gson();
        HashMap map = gson.fromJson(result, HashMap.class);
        Object errcode = map.get("errcode");
        if(null!=errcode){
            String errmsg = (String)map.get("errmsg");
            Double errorCode = (Double)errcode;
            log.error("获取access_token失败 - " + "message: " + errmsg + ", errcode: " + errorCode);
            throw new GuliException(ResultCodeEnum.FETCH_ACCESSTOKEN_FAILD);
        }
        String  accessToken = (String) map.get("access_token");
        String  openid = (String) map.get("openid");

        Member member = memberService.getByOpenid(openid);
        if(null==member){
            String userInfoUrl="https://api.weixin.qq.com/sns/userinfo?" +
                    "access_token=" +accessToken+
                    "&openid="+openid;
            client=new HttpClientUtils(userInfoUrl);
            String resultUser="";
            try {
                client.setHttps(true);
                client.get();
                resultUser = client.getContent();
            } catch (Exception e) {
                log.error(ExceptionUtils.getStackTrace(e));
                throw new GuliException(ResultCodeEnum.FETCH_USERINFO_ERROR);
            }
            HashMap userMap = gson.fromJson(resultUser, HashMap.class);
            if(null!=userMap.get("errcode")){
                log.error("获取用户信息失败" + "，message：" + userMap.get("errmsg"));
                throw new GuliException(ResultCodeEnum.FETCH_USERINFO_ERROR);
            }
            member=new Member();
            member.setOpenid(openid);
            member.setNickname((String) userMap.get("nickname"));
            R r = ossFileService.uploadFromUrl((String) userMap.get("headimgurl"), "avatar");
            String  url = (String) r.getData().get("url");
            member.setAvatar(url);
//            member.setAvatar((String) userMap.get("headimgurl"));
            member.setSex(((Double)userMap.get("sex")).intValue());
            memberService.save(member);
        }
        JwtInfo jwtInfo=new JwtInfo();
        jwtInfo.setId(member.getId());
        jwtInfo.setAvatar(member.getAvatar());
        jwtInfo.setNickname(member.getNickname());
        String token = JwtHelper.createToken(jwtInfo);
//        ModelAndView mv=new ModelAndView();
//        mv.setViewName("http://localhost:3000");
//        mv.addObject("token",token);
//        return mv;
        return "redirect:http://localhost:3000?token="+token;
    }
}
